/**
 * Copyright (c) 2016-2023, Michael Yang 杨福海 (fuhai999@gmail.com).
 * <p>
 * Licensed under the GNU Lesser General Public License (LGPL) ,Version 3.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.gnu.org/licenses/lgpl-3.0.txt
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.jpress;

import com.jfinal.config.Constants;
import com.jfinal.config.Interceptors;
import com.jfinal.config.Routes;
import com.jfinal.core.converter.TypeConverter;
import com.jfinal.kit.CPI;
import com.jfinal.template.Engine;
import io.jboot.Jboot;
import io.jboot.aop.jfinal.JfinalHandlers;
import io.jboot.app.config.JbootConfigManager;
import io.jboot.components.cache.JbootCache;
import io.jboot.components.cache.JbootCacheManager;
import io.jboot.components.cache.support.JbootCaptchaCache;
import io.jboot.core.listener.JbootAppListenerBase;
import io.jboot.core.weight.Weight;
import io.jboot.web.attachment.AttachmentManager;
import io.jboot.web.xss.XSSHandler;
import io.jpress.commons.url.FlatUrlHandler;
import io.jpress.core.addon.AddonManager;
import io.jpress.core.addon.controller.AddonControllerProcesser;
import io.jpress.core.addon.handler.AddonHandlerProcesser;
import io.jpress.core.editor.EditorManager;
import io.jpress.core.menu.MenuManager;
import io.jpress.core.site.SiteManager;
import io.jpress.core.template.BlockFunctions;
import io.jpress.core.template.TemplateFilesWatcher;
import io.jpress.core.web.TypeConverterFunc;
import io.jpress.core.wechat.WechatAddonManager;
import io.jpress.pro.addon.ProAddonNotifier;
import io.jpress.pro.attachment.aliyun.AliyunOssAttachmenetContainer;
import io.jpress.pro.attachment.aliyun.AliyunOssAttachmentConfig;
import io.jpress.pro.attachment.minio.MinioAttachmentConfig;
import io.jpress.pro.attachment.minio.MinioAttachmentContainer;
import io.jpress.pro.filesync.FileSyncConfig;
import io.jpress.pro.filesync.SyncFilesWatcher;
import io.jpress.pro.options.ProOptionNotifier;
import io.jpress.pro.options.ProOptionsStore;
import io.jpress.web.handler.JPressHandler;
import io.jpress.web.handler.SiteHandler;
import io.jpress.web.interceptor.JPressInterceptor;
import io.jpress.web.interceptor.UTMInterceptor;
import io.jpress.web.render.JPressRenderFactory;
import io.jpress.web.sitemap.SitemapHandler;
import io.jpress.web.sitemap.SitemapManager;

/**
 * @author Michael Yang 杨福海 （fuhai999@gmail.com）
 * @version V1.0
 * @Title: JPress 初始化工具
 * @Package io.jpress
 */
@Weight(100)
public class JPressCoreInitializer extends JbootAppListenerBase {


    @Override
    public void onInit() {

        if (Jboot.getMq() != null) {
            JPressOptions.setStoreLoader(siteId -> new ProOptionsStore());
            JPressOptions.setNotifier(new ProOptionNotifier());

            AddonManager.me().setNotifier(new ProAddonNotifier());
        }
    }


    @Override
    public void onConstantConfig(Constants constants) {
        constants.setRenderFactory(new JPressRenderFactory());
        constants.setCaptchaCache(new JbootCaptchaCache());
        CPI.setRetMsgName("message");

        JbootCache cache = JbootCacheManager.me().getCache();
        cache.addThreadCacheNamePrefixIngores("user_sessions", "user_permission", "user_role", "useropenid", "site_info"
                , "_aj_captcha", "jboot_captchas", "jboot_tokens", "wechat_access_tokens");
    }

    @Override
    public void onRouteConfig(Routes routes) {
        routes.setClearAfterMapping(false);
    }


    @Override
    public void onHandlerConfig(JfinalHandlers handlers) {

        handlers.add(new SitemapHandler());
        handlers.add(new JPressHandler());
        handlers.add(new SiteHandler());
        handlers.add(new FlatUrlHandler());
        handlers.add(new AddonHandlerProcesser());
        handlers.add(new XSSHandler());

        handlers.setActionHandler(new AddonControllerProcesser());
    }


    @Override
    public void onEngineConfig(Engine engine) {
        engine.addSharedStaticMethod(BlockFunctions.class);
    }


    @Override
    public void onInterceptorConfig(Interceptors interceptors) {
        interceptors.add(new UTMInterceptor());
        interceptors.add(new JPressInterceptor());
    }

    @Override
    public void onStart() {

        SitemapManager.me().init();
        MenuManager.me().init();
        WechatAddonManager.me().init();
        AddonManager.me().init();
        EditorManager.me().init();
        SiteManager.me().init();


        AttachmentManager.me().getDefaultContainer().setRootPath(JPressConfig.me.getAttachmentRootOrWebRoot());

        //添加 阿里云 OSS 附件容器
        AliyunOssAttachmentConfig ossAttachmentConfig = JbootConfigManager.me().get(AliyunOssAttachmentConfig.class);
        if (ossAttachmentConfig.isEnable()) {
            AttachmentManager.me().addContainer(new AliyunOssAttachmenetContainer());
        }

        //添加 Minio 附件容器
        MinioAttachmentConfig config = JbootConfigManager.me().get(MinioAttachmentConfig.class);
        if (config.isEnable()) {
            AttachmentManager.me().addContainer(new MinioAttachmentContainer());
        }


        if (Jboot.getMq() != null) {
            TemplateFilesWatcher.me().start();
            Jboot.getMq().startListening();
        }


        if (FileSyncConfig.getInstance().isEnable()) {
            SyncFilesWatcher.me().start();
        }

    }

    @Override
    public void onStartFinish() {
        TypeConverter.me().setConvertFunc(new TypeConverterFunc());
    }
}
